<template>
	<ucs-layout :backgroundColor="props.backgroundColor" :isSafeArea="props.isSafeArea" :safeAreaColor="props.safeAreaColor">
		<template v-slot:header>
			<slot name="header" />
		</template>

		<!-- 缺省页状态 -->
		<view v-if="!dataWorkers.isReady">
			<ucs-empty-loading v-if="isLoading" :offset-top="32" :offset-bottom="32" />
		</view>
		<view v-else-if="!dataWorkers.isData && dataWorkers.isReady">
			<view v-if="props.status== 200">
				<ucs-empty-data :offset-top="32" :offset-bottom="32" />
			</view>
			<view v-else-if="props.status== 403">
				<ucs-empty-auth :offset-top="32" :offset-bottom="32" />
			</view>
			<view v-else-if="props.status== 404">
				<ucs-empty-error-page :offset-top="32" :offset-bottom="32" />
			</view>
			<view v-else-if="props.status== 500">
				<ucs-empty-fail :offset-top="32" :offset-bottom="32" />
			</view>
			<view v-else>
				<ucs-empty-network :offset-top="32" :offset-bottom="32" desc="未知错误，请稍后重试" />
			</view>
		</view>
		<!-- 正常数据渲染 -->
		<view v-else>
			<slot />
			<ucs-load-more :status="dataWorkers.loadMoreStatus" />
		</view>

		<template v-slot:sign>
			<slot name="sign" />
		</template>

		<template v-slot:footer>
			<slot name="footer" />
		</template>
	</ucs-layout>
</template>

<script setup lang="uts">
	import { reactive, watch, onUnmounted } from "vue";
	// @ts-ignore
	import { onPullDownRefresh, onLoad, onShow, onReachBottom } from "@dcloudio/uni-app";

	// 超过设定时间区间未加载数据则显示加载中状态
	const isLoading = ref<boolean>(false);
	const isLoadingVar = setTimeout(() => {
		isLoading.value = true;
	}, 300);

	const emits = defineEmits(['change']);

	const props = defineProps({
		backgroundColor: {
			type: String,
			default: "transparent"
		},
		isSafeArea: {
			type: Boolean,
			default: true
		},
		safeAreaColor: {
			type: String,
			default: "transparent"
		},
		period: {
			type: String,
			default: "onReady"
		},
		status: {
			type: Number,
			default: 200
		},
		data: {
			type: Array,
			default: () => {
				return []
			}
		}
	});

	type DataWorkersType = {
		isReady : boolean;
		isData : boolean;
		onePageDataNumber : number;
		totalDataNumber : number;
		isAchieve : boolean;
		isDeleteAfter : boolean;
		loadMoreStatus : string;
		isRefresh : boolean;
		isReachBottom : boolean;
		onLoadValue : UTSJSONObject;
	}
	// 数据状态
	let dataWorkers = reactive<DataWorkersType>({
		isReady: false,
		isData: false,
		onePageDataNumber: 0,
		totalDataNumber: 0,
		isAchieve: false,
		isDeleteAfter: false,
		loadMoreStatus: "none",
		isRefresh: false,
		isReachBottom: true,
		onLoadValue: {}
	});

	// 监听函数状态
	watch(() : number => props.status, () => {
		dataWorkers.isReady = true;
		uni.stopPullDownRefresh();
	});
	// @ts-ignore
	watch(() : Array => props.data, (newVal : Array, oldVal : Array) => {
		// 初始化一页数据条数
		const newOldGap = newVal.length - oldVal.length;
		// 每页数量
		dataWorkers.onePageDataNumber = newOldGap > dataWorkers.onePageDataNumber ? newOldGap : dataWorkers.onePageDataNumber;
		// 是否删除过数据
		if (newOldGap == 0 && dataWorkers.totalDataNumber > newVal.length) {
			dataWorkers.isDeleteAfter = true;
		} else {
			dataWorkers.isDeleteAfter = false;
		};
		// 是否数据全部加载完成
		if (newOldGap < dataWorkers.onePageDataNumber || newVal.length == 0) {
			dataWorkers.isAchieve = true;
		} else {
			dataWorkers.isAchieve = false;
		};
		// 是否已加载
		dataWorkers.isReady = true;
		// true ：存在数据，false：无数据
		dataWorkers.isData = newVal.length > 0 ? true : false;
		// 记录总数居数量
		dataWorkers.totalDataNumber = newVal.length;
		// 处理当刷新后加载状态判定
		if (dataWorkers.totalDataNumber < dataWorkers.onePageDataNumber) {
			dataWorkers.loadMoreStatus = "none";
		};
		// 上拉加载更多
		if (dataWorkers.loadMoreStatus != "none") {
			if (newVal.length >= oldVal.length) {
				dataWorkers.loadMoreStatus = "nomore"
			} else {
				dataWorkers.loadMoreStatus = "loadmore"
			};
		};
		// 关闭下拉刷新
		if (dataWorkers.isRefresh) {
			uni.stopPullDownRefresh();
			dataWorkers.isRefresh = false;
		};
		// 解锁上拉加载
		dataWorkers.isReachBottom = true;
	}, {
		deep: true
	});

	const refresh = () => {
		dataWorkers.isRefresh = true;
		dataWorkers.isAchieve = false;
		emits("change", {
			"onPullDownRefresh": true,
			"onReachBottom": false,
			"loadmorePage": 1,
			"onLoadValue": dataWorkers.onLoadValue
		});
	};

	const refreshLoading = () => {
		dataWorkers.isReady = false;
		dataWorkers.isRefresh = true;
		dataWorkers.isAchieve = false;
		emits("change", {
			"onPullDownRefresh": true,
			"onReachBottom": false,
			"loadmorePage": 1,
			"onLoadValue": dataWorkers.onLoadValue
		});
	};

	// 触发上拉加载
	onReachBottom(() => {
		dataWorkers.loadMoreStatus = "loading";
		// 向上取整
		const mathCeil = Math.ceil(dataWorkers.totalDataNumber / dataWorkers.onePageDataNumber) + 1;
		// 向下取整
		const mathFloor = Math.floor(dataWorkers.totalDataNumber / dataWorkers.onePageDataNumber) + 1;

		if (dataWorkers.isReachBottom) {
			emits("change", {
				"onPullDownRefresh": false,
				"onReachBottom": true,
				"loadmorePage": dataWorkers.isAchieve && !dataWorkers.isDeleteAfter ? mathCeil : mathFloor,
				"onLoadValue": dataWorkers.onLoadValue
			});
		};
		// 锁定上拉加载
		dataWorkers.isReachBottom = false;
	});

	// 下拉刷新
	onPullDownRefresh(() => {
		refresh();
	});
	// 页面加载调用
	if (props.period == "onReady") {
		refresh();
	};
	// 页面显示即调用
	onShow(() => {
		if (props.period == "onShow") {
			refresh();
		};
	});
	onLoad((e : UTSJSONObject) => {
		if (props.period == "onLoad") {
			dataWorkers.onLoadValue = e;
			refresh();
		};
	});
	// 暴露方法
	defineExpose({
		refresh, refreshLoading
	});
	// 卸载组件
	onUnmounted(() => {
		clearInterval(isLoadingVar);
	});
</script>

<style>

</style>